package _06_动态规划;

public class _72_编辑距离 {

    public static void main(String[] args) {
        _72_编辑距离 v = new _72_编辑距离();
        String str1 = "arise";
        String str2 = "mice";
        System.out.println(v.minDistance(str1, str2));
    }


    public int minDistance(String word1, String word2) {
        if (word1.length() == 0) return word2.length();
        if (word2.length() == 0) return word1.length();
        if (word1.equals(word2)) return 0;
        char[] rowEle = word2.toCharArray();
        char[] colEle = word1.toCharArray();
        if (colEle.length > rowEle.length) {
            char[] temp = colEle;
            colEle = rowEle;
            rowEle = temp;
        }
        int rows = rowEle.length;
        int cols = colEle.length;
        int[] dp = new int[cols + 1];
        for (int col = 1; col <= cols; col++) {
            dp[col] = col;
        }
        // 推到dp值
        for (int row = 1; row <= rows; row++) {
            int cur = dp[0] = row - 1;
            for (int col = 1; col <= cols; col++) {
                int prev = cur;
                cur = dp[col];
                int top = dp[col] + 1;
                int left = dp[col - 1] + 1;
                int leftTop = prev + (rowEle[row - 1] == colEle[col - 1]? 0: 1);
                // 取三者最小值
                dp[col] = Math.min(Math.min(left, top), leftTop);
            }
        }
        return dp[cols];
    }


    // 最小编辑距离
    public int minDistance1(String word1, String word2) {
        if (word1.length() == 0) return word2.length();
        if (word2.length() == 0) return word1.length();
        if (word1.equals(word2)) return 0;
        char[] chars1 = word1.toCharArray();
        char[] chars2 = word2.toCharArray();
        int rows = chars1.length;
        int cols = chars2.length;
        // 定义dp数组，dp[i][j] 表示chars1以i结尾， chars2以j结尾的最小编辑距离
        int[][] dp = new int[rows + 1][cols + 1];
        // 设置初始值
        for (int row = 1; row <= rows; row++) {
            dp[row][0] = row;
        }
        for (int col = 1; col <= cols; col++) {
            dp[0][col] = col;
        }
        // 推到dp值
        for (int row = 1; row <= rows; row++) {
            for (int col = 1; col <= cols; col++) {
                int top = dp[row - 1][col] + 1;
                int left = dp[row][col - 1] + 1;
                int leftTop = dp[row - 1][col - 1] + (chars1[row - 1] == chars2[col - 1]? 0: 1);
                // 取三者最小值
                dp[row][col] = Math.min(Math.min(left, top), leftTop);
            }
        }
        return dp[rows][cols];
    }

}
